package xiyuan.keywords.tfidf;


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import xiyuan.data.Frequency;
import xiyuan.data.FrequencyDAO;
import xiyuan.keywords.split.Word;


public class TfidfTool {
	private static FrequencyDAO dao = new FrequencyDAO();
	private static final int totalFiles = 173144;
	private List<KeyWord> keywords;

	/*
	 * //changed private static final Logger log = LoggerFactory
	 * .getLogger(WordBankDAO.class); // property constants public static final
	 * String ID = "id"; public static final String UID = "uid"; public static
	 * final String KEYWORD = "keyword"; public static final String WEIGHT =
	 * "weight";
	 * 
	 * public void save(WordBank transientInstance) {
	 * log.debug("saving keyword instance"); Transaction tran =
	 * getSession().beginTransaction(); try {
	 * getSession().save(transientInstance); log.debug("save successful"); }
	 * catch (RuntimeException re) { log.error("save failed", re); throw re; }
	 * tran.commit(); }
	 * 
	 * public void delete(WordBank persistentInstance) {
	 * log.debug("deleting keyword instance"); try {
	 * getSession().delete(persistentInstance); log.debug("delete successful");
	 * } catch (RuntimeException re) { log.error("delete failed", re); throw re;
	 * } }
	 * 
	 * public WordBank findById(java.lang.Integer id) {
	 * log.debug("getting keyword instance with id: " + id); try { WordBank
	 * instance = (WordBank) getSession() .get("data.keyword", id); return
	 * instance; } catch (RuntimeException re) { log.error("get failed", re);
	 * throw re; } }
	 * 
	 * public List findByExample(WordBank instance) {
	 * log.debug("finding WordBank instance by example"); try { List results =
	 * getSession().createCriteria("data.keyword")
	 * .add(Example.create(instance)).list();
	 * log.debug("find by example successful, result size: " + results.size());
	 * return results; } catch (RuntimeException re) {
	 * log.error("find by example failed", re); throw re; } }
	 * 
	 * public List findByProperty(String propertyName, Object value) {
	 * log.debug("finding WordBank instance with property: " + propertyName +
	 * ", value: " + value); try { String queryString =
	 * "from WordBank as model where model." + propertyName + "= ?"; Query
	 * queryObject = getSession().createQuery(queryString);
	 * queryObject.setParameter(0, value); return queryObject.list(); } catch
	 * (RuntimeException re) { log.error("find by property name failed", re);
	 * throw re; } }
	 * 
	 * public List findById(Object id) { return findByProperty(ID, id); }
	 * 
	 * public List findByUid(Object uid) { return findByProperty(UID, uid); }
	 * 
	 * public List findByKeyword(Object keyword) { return
	 * findByProperty(KEYWORD, keyword); }
	 * 
	 * public List findByWeight(Object weight) { return findByProperty(WEIGHT,
	 * weight); }
	 * 
	 * public List findAll() { log.debug("finding all WordBank instances"); try
	 * { String queryString = "from TdifTool"; Query queryObject =
	 * getSession().createQuery(queryString); return queryObject.list(); } catch
	 * (RuntimeException re) { log.error("find all failed", re); throw re; } }
	 * 
	 * public TfidfTool merge(WordBank detachedInstance) {
	 * log.debug("merging WordBank instance"); try { TfidfTool result =
	 * (TfidfTool) getSession().merge(detachedInstance);
	 * log.debug("merge successful"); return result; } catch (RuntimeException
	 * re) { log.error("merge failed", re); throw re; } }
	 * 
	 * public void attachDirty(WordBank instance) {
	 * log.debug("attaching dirty WordBank instance"); try {
	 * getSession().saveOrUpdate(instance); log.debug("attach successful"); }
	 * catch (RuntimeException re) { log.error("attach failed", re); throw re; }
	 * }
	 * 
	 * public void attachClean(WordBank instance) {
	 * log.debug("attaching clean WordBank instance"); try {
	 * getSession().lock(instance, LockMode.NONE);
	 * log.debug("attach successful"); } catch (RuntimeException re) {
	 * log.error("attach failed", re); throw re; } }
	 */

	/**
	 * use a list of Words to generate a list of keywords
	 */
	public TfidfTool(List<Word> list) {
		// get a list of words used by uid
		//System.out.println("uid " + uid + " is set");// debug
		//List list = dao.findByUid(uid);
		int totalWords = list.size();
		Map<String, Integer> map = new HashMap<String, Integer>();
		Map<String, Double> map2 = new HashMap<String, Double>(); // 放词性权重
		List<KeyWord> tfidfList = new ArrayList<KeyWord>();
		// record the frequency of each word for this user
		for (Word cur : list) {
			//System.out.println("the for cycle begin");
			String word = cur.getWord(); // get the word type
			// System.out.println(cur.getType());
			double rank = cixing(cur.getAttribute());
			// System.out.println(word + " " + cur.getType() + " " + rank);
			map2.put(word, rank);
			if (!map.containsKey(word)) {
				map.put(word, 1);
			} else {
				map.put(word, map.get(word) + 1);
			}
		}
		//System.out.println("can u see it?map.size = " + map.size());
		if (map.size() == 0)
			return;
		//List freqList =daoD.findByProperty("id.word", map.keySet().toArray()[0]);
		List freqList = dao.findByPropertyList("word", map.keySet()
				.toArray());
		
		Frequency curD;
		//System.out.println("can u see it?3");
		int setten = 0;
		// get the occurence frequency of this word in the data set
		for (Object curObj : freqList) {
			curD = (Frequency) curObj;
			String key = curD.getWord();
			Long count = curD.getCount();
			double tf = 1.0 * map.get(key) / totalWords;
			double idf = Math.log(1.0 * totalFiles / count);
			double posi = map2.get(key);
			System.out.println(setten);// debug
			tfidfList.add(new KeyWord(key, tf * idf * posi));
		}
		//System.out.println("can u see it?2");
		// sort the map of key words
		Collections.sort(tfidfList, Collections.reverseOrder());
		keywords = tfidfList;
	}

	/**
	 * return the top N keywords
	 * @param num
	 * @return
	 */
	public List<KeyWord> getKeywords(int num){
		if (keywords == null)
			return null;
		if(keywords.size()>=num)
			return keywords.subList(0, num-1);
		else
			// same as return keywords.clone(); 
			// but i cannot find that function
			return keywords.subList(0, keywords.size() - 1);
	}
	
	private double cixing(String s)// 词性权重
	{
		String choices[] = { "n", "nr", "ns", "t", "s", "f", "v", "a", "b",
				"z", "r", "m", "q", "d", "p", "c", "u", "e", "y", "o", "h",
				"k", "x", "w", "ad", "an", "vd", "vn" };
		for (int i = 0; i < 28; i++) {
			if (s.equals(choices[i])) {
				switch (i) {
				case 7:
					return 0.5;
				case 24:
				case 6:
					return 0.3;
				case 25:
				case 27:
					return 0.6;
				case 26:
					return 0.4;
				case 0:
					return 0.8;
				}
			} else if (s.substring(0, 1).equals(choices[i])) {
				switch (i) {
				case 0:
					return 0.8;
				case 6:
					return 0.3;
				case 7:
				case 10:
					return 0.5;
				}
			}
		}
		return 1;
	}
}